var map;
var images = [
  "http://maps.google.com/mapfiles/marker.png",
  "http://maps.google.com/mapfiles/dd-start.png",
  "http://maps.google.com/mapfiles/dd-end.png"
];

var Bus = {
    id: 0,
    form: null,

    _routes: {},
    _activeMarker: 0,

    getForm: function() {
        if (this.form == null) {
            this.form = $('#form_bus');
        }
        return this.form;
    },

    resetForm: function()
    {
        this.getForm().get(0).reset();
        $('#bus_pid').val(0);
        $('#bus_routes-element .bus_route').remove();
        this.resetActiveMarker();
        for (var i in this._routes) {
            this._routes[i].setMap(null);
            delete this._routes[i];
        }
        this._routes = {};
    },

    getRoutesJson: function()
    {
        var routes = [], points;
        for (var i in this._routes) {
            if (!this._routes[i]) {
                continue;
            }
            points = i.split('_');
            routes.push({from: points[0], to: points[1]});
        }
        return routes;
    },

    onSubmit: function()
    {
        // encode routes
        $('#bus_routes').val(JSON.stringify(Bus.getRoutesJson()));

        var form = $('#form_bus');
        var data = form.serialize();
        $.ajax({
            type: 'post',
            url: form.attr('action'),
            data: data,
            dataType: 'json',
            success: function(response) {
                if (response.errors) {
                    alert(response.errors.join("\n"));
                    return;
                }
                Bus.getForm().hide();
                Bus.resetForm();
                Bus.reloadList();
            }
        });
        return false;
    },

    reloadList: function()
    {
        $.getJSON(BASE_URL + '/bus/bus/list', function(response) {
            if (response.errors) {
                alert(response.errors.join("\n"));
                return;
            }
            var data = response.data, item;
            var html = '';
            for (var i in data) {
                item = data[i];
                html += '<a href="#" id="bus_'+item.bus_pid+'" ' 
                     + 'bus_id="'+item.bus_pid+'" class="bus-item">'
                     + item.bus_name
                     + '</a> ';
            }
            $('#bus_list').html(html);
        });
    },

    edit: function(id)
    {
        Bus.resetForm();
        $.getJSON(BASE_URL + '/bus/bus/load/id/' + id, function(response){
            if (response.errors) {
                alert(response.errors.join("\n"));
                return;
            }
            for (var i in response) {
                $('#' + i).val(response[i]);
            }
            for (var i in response.routes) {
                Bus.addRoute(response.routes[i].from, response.routes[i].to);
            }
            Bus.getForm().show();
            $('#bus_delete-element').show();
        });
    },

    removeRoute: function(route_key)
    {
        this._routes[route_key].setMap(null);
        delete this._routes[route_key];
        $('#route_' + route_key).remove();
    },

    addRoute: function(from_id, to_id)
    {
        var route_key = from_id + '_' + to_id;
        if (this._routes[route_key]) {
            alert('Such route already exists, removing.');
            this.removeRoute(route_key);
            return;
        }
        var marker_from = Stop.getStop(from_id);
        var marker_to = Stop.getStop(to_id);
        
        var coordinates = [
            marker_from.getPosition(),
            marker_to.getPosition()
        ];
        var route = new google.maps.Polyline({
            path: coordinates,
            strokeColor: "#FF0000",
            strokeOpacity: 1.0,
            strokeWeight: 2
        });
        route.from_id = from_id;
        route.to_id = to_id;
        this._routes[route_key] = route;
        route.setMap(map);

        var html = '<div id="route_' + route_key + '" class="bus_route">' + marker_from.getTitle()
                 + ' -&gt; ' + marker_to.getTitle() + '</div>';
        $('#bus_routes-element').append(html);
    },

    onMarkerClick: function(marker, e)
    {
        if (this._activeMarker) {
            if (marker.bus_stop_pid == this._activeMarker.bus_stop_pid) {
                this.resetActiveMarker();
                return;
            }
            this.addRoute(this._activeMarker.bus_stop_pid, marker.bus_stop_pid);
        }
        this.resetActiveMarker();
        this.setActiveMarker(marker);
    },

    setActiveMarker: function(marker)
    {
        this._activeMarker = marker;
        marker.setIcon(images[1]);
    },

    resetActiveMarker: function()
    {
        if (this._activeMarker) {
            this._activeMarker.setIcon(images[0]);
            this._activeMarker = 0;
        }
    },

    remove: function()
    {
        if (!confirm('Remove bus?')) {
            return;
        }
        $.ajax({
            type: 'POST',
            url: BASE_URL + '/bus/bus/remove',
            data: {
                id: $('#bus_pid').val()
            },
            dataType: 'json',
            success: function(response) {
                if (response.errors) {
                    alert(response.errors.join("\n"));
                    return;
                }
                Bus.getForm().hide();
                Bus.resetForm();
                Bus.reloadList();
            }
        });
    }
}

var Stop = {
    form: null,
    stop: null,
    _marker: null,
    _markers: {},
    
    getForm: function()
    {
        if (this.form == null) {
            this.form = $('#form_stop');
        }
        return this.form;
    },

    follow: function()
    {
        if (Stop._marker != null) {
            alert('Save or Cancel current item before this action.');
            return;
        }
        var marker;
        var dog = true;
        var noMore = false;
        var markerClick;

        var mouseMove = google.maps.event.addListener(map, 'mousemove', function(cursorPoint){
            if (!noMore) {
                marker = new google.maps.Marker({
                     position: cursorPoint.latLng
                    ,draggable:true
                    ,autoPan:false
                    ,map: map
                    //,icon: images[imageInd]
                });
                markerClick = google.maps.event.addListener(marker, 'click', function(e){
                    if (dog) {
                        dog = false;
                        google.maps.event.removeListener(mouseMove);
                        google.maps.event.removeListener(mapClick);
                        google.maps.event.removeListener(markerClick);
                        Stop.create(marker);
                    }
                });
                noMore = true;
                // This function deletes the marker when dragged outside map
                google.maps.event.addListener(marker, 'drag', function(markerPoint){
                    $('#coord_lat').val(markerPoint.latLng.lat());
                    $('#coord_lng').val(markerPoint.latLng.lng());
                });
                Stop._marker = marker;
            }
            if (dog) {
                marker.setPosition(cursorPoint.latLng);
            }
        });

        var mapClick = google.maps.event.addListener(map, 'click', function(cursorPoint){
            if (dog) {
                dog = false;
                google.maps.event.removeListener(mouseMove);
                google.maps.event.removeListener(mapClick);
                google.maps.event.removeListener(markerClick);
                Stop.create(marker);
            }
        });
    },

    create: function(marker)
    {
        this._marker = marker;
        this.resetForm();
        $('#coord_lat').val(marker.getPosition().lat());
        $('#coord_lng').val(marker.getPosition().lng());
        this.getForm().show();
        $("#tabs").tabs('select', 1);
    },

    resetForm: function()
    {
        $('#bus_stop_pid').val(0);
        this.getForm().get(0).reset();
    },

    onSubmit: function()
    {
        var form = Stop.getForm();
        $.ajax({
            type: 'post',
            url: form.attr('action'),
            data: form.serialize(),
            dataType: 'json',
            success: function(response) {
                if (response.errors) {
                    alert(response.errors.join("\n"));
                    return;
                }
                Stop.getForm().hide();
                if (Stop._marker && !Stop._marker.bus_stop_pid) {
                    Stop._marker.setMap(null);
                } else {
                    Stop._marker.setDraggable(false);
                }
                Stop._marker = null;
                Stop.reloadList();
            }
        });
        return false;
    },

    reloadList: function()
    {
        $.getJSON(BASE_URL + '/bus/stop/list', function(response) {
            if (response.errors) {
                alert(response.errors.join("\n"));
                return;
            }
            var data = response.data, item, marker;
            for (var i in data) {
                item = data[i];
                if (Stop._markers[item.bus_stop_pid]) {
                    // update exists marker
                    marker = Stop._markers[item.bus_stop_pid];
                    // update position
                    var cur_pos = marker.getPosition();
                    if (cur_pos.lat() != item.coord_lat || cur_pos.lng() != item.coord_lng) {
                        marker.setPosition(
                            new google.maps.LatLng(item.coord_lat, item.coord_lng)
                        );
                    }
                    marker.setTitle(item.stop_name);
                } else {
                    // add new marker
                    var pos = new google.maps.LatLng(item.coord_lat, item.coord_lng);
                    marker = new google.maps.Marker({
                         position: pos
                        ,draggable: false
                        ,autoPan: false
                        ,map: map
                        ,title: item.stop_name
                        //,icon: images[imageInd]
                    });
                    google.maps.event.addListener(marker, 'click', Stop.onMarkerClick);
                    google.maps.event.addListener(marker, 'drag', Stop.onMarkerDrag);
                    Stop._markers[item.bus_stop_pid] = marker;
                    marker.bus_stop_pid = item.bus_stop_pid;
                }
            }
        });
    },

    onMarkerClick: function(e)
    {
        if (Bus.getForm().css('display') == 'block') {
            Bus.onMarkerClick(this, e);
            return;
        }
        this.setDraggable(true);
        Stop.resetForm();
        Stop.getForm().show();
        $('#bus_stop_pid').val(this.bus_stop_pid);
        $('#stop_name').val(this.getTitle());
        $('#coord_lat').val(this.getPosition().lat());
        $('#coord_lng').val(this.getPosition().lng());
        Stop._marker = this;
        $("#tabs").tabs('select', 1);
    },

    onMarkerDrag: function(markerPoint)
    {
        $('#coord_lat').val(markerPoint.latLng.lat());
        $('#coord_lng').val(markerPoint.latLng.lng());
    },

    onCancel: function()
    {
        if (!Stop._marker.bus_stop_pid) {
            Stop._marker.setMap(null);
        }
        Stop._marker.setDraggable(false);
        Stop._marker = null;
        Stop.reloadList();
        Stop.getForm().hide();
    },

    getStop: function(id)
    {
        return this._markers[id];
    }
}